﻿using Ldt.DataEngine.DataFlowParse.Model;
using Ldt.InformationUnit.Common;
using LdtDataEngin.ModuleDetail.BaseModule.Optimization;
using LdtJudge.DataEngine.CallInterface.ConfiCenter;
using LdtJudge.DataEngine.Common;
using LdtJudge.DataEngine.Common.CommHelp;
using LdtJudge.DataEngine.Common.XmlUtility;
using LdtJudge.DataEngine.DataBaseStores;
using LdtJudge.DataEngine.Model.Collection;
using LdtJudge.DataEngine.Model.XMLConfigModel.DataStores;
using LdtJudge.DataEngine.Model.XMLConfigModel.OptimizeConfigModel.StagOptimization;
using LdtJudge.DataEngine.Model.XMLConfigModel.SameNodeConfigModel;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text.RegularExpressions;
using System.Xml;
using System.Xml.Linq;

namespace LdtDataEngin.ModuleDetail.OptimizationModule.StageOptimization
{
    /// <summary>
    /// 阶段性优选操作模块
    /// </summary>
    public class StageOpt : OptimizationBase
    {
        /// <summary>
        /// 要素定位配置信息
        /// </summary>
        public DOCLocationModel locationModel { get; set; }

        private List<ConfigModel> configModels = new List<ConfigModel>();

        /// <summary>
        /// 同节点配置
        /// </summary>
        private SameNodeConfig sameNodeConfig = null;

        /// <summary>
        /// 构造
        /// </summary>
        public StageOpt(DataContext dataContext, string moduleName)
        {
            this.dataContext = dataContext;
            this.ModuleName = moduleName;
            ParseConfig();
        }

        /// <summary>
        /// 解析配置
        /// </summary>
        public void ParseConfig()
        {
            if (this.dataContext.DataLayerSys.GetConfigModel(ModuleName).ConfigDetail != null)
            {
                List<DOCLocationModel> locationModelList = new List<DOCLocationModel>();
                var configDetails = this.dataContext.DataLayerSys.GetConfigModel(ModuleName).ConfigDetail;
                string causeLocalContent = string.Empty;
                string causeStageContent = string.Empty;
                configModels.AddRange(configDetails.Where(x => x.Code.ToLower() != "causelocation" && x.Code.ToLower() != "causestagelocation"));
                ConfigModel causeLocalConfig = configDetails.FirstOrDefault(x => x.Code.ToLower() == "causelocation");
                if (causeLocalConfig != null)
                    causeLocalContent = causeLocalConfig.ConfigContent;
                ConfigModel causeStageConfig = configDetails.FirstOrDefault(x => x.Code.ToLower() == "causestagelocation");
                if (causeStageConfig != null)
                    causeStageContent = causeStageConfig.ConfigContent;
                ParseLocationConfig locationConfigM = new ParseLocationConfig();
                locationModelList = locationConfigM.GetLocationModel(causeLocalContent, causeStageContent, dataContext.DataLayerOpt.OptimizationXml, dataContext.DataLayerAns.CaseType, dataContext.DataLayerAns.SourceCode);
                locationModel = locationModelList.FirstOrDefault(x => x.DocType.ToLower() == dataContext.DataLayerAns.SourceCode.ToLower());
                GetSameNodeConfig();
            }
        }

        /// <summary>
        /// 执行阶段性优选
        /// </summary>
        public void ExeStageOpt()
        {
            Stopwatch stopwatch = new Stopwatch();
            SetModuleProcess(ModuleName, 0,dataContext.InteractiveShow.inputParameterModel);
            stopwatch.Start();
           
            try
            {   
                if (!string.IsNullOrEmpty(configModels.First().ConfigContent))
                {
                    ConfigModel spanStageOptConfig = configModels.FirstOrDefault(a => a.Code.ToLower()== "spanstageopt");
                    ConfigModel spanStageLocateConfig = configModels.FirstOrDefault(a => a.Code.ToLower() == "stagelocate");
                    StageOptimization(spanStageOptConfig?.ConfigContent,spanStageLocateConfig?.ConfigContent,sameNodeConfig);
                    dataContext.DataLayerOpt.SourdatModleList = dataContext.DataLayerOpt.SourdatModleList.Where(a => a.State != "2").ToList();
                    dataContext.DataLayerOpt.SourdatModleList = dataContext.DataLayerOpt.SourdatModleList.Distinct().ToList();
                    XmlDocument xmlDocumentOp = XmlUtility.DataModelByXml(dataContext.DataLayerOpt.SourdatModleList);
                    dataContext.DataLayerOpt.OptimizationXml = xmlDocumentOp;
                }
            }
            catch (Exception ex)
            {
                dataContext.InteractiveShow.LogShow("阶段性优选错误:" + ex.ToString());
            }

            stopwatch.Stop();
            SetModuleProcess(ModuleName + "_" + stopwatch.Elapsed.TotalMilliseconds.ToString("0"), 100,dataContext.InteractiveShow.inputParameterModel);
        }

        /// <summary> 
        /// 阶段性优选开始
        /// </summary>
        /// <param name="stageopConfig"></param>
        public void StageOptimization(string stageopConfig,string stageModeConfig,SameNodeConfig sameNodeConfig)
        {
            StageConfig stageModelConfig = XmlUtility.DeserializeToObject<StageConfig>(stageModeConfig);
            bool fage = false;
            if (dataContext.DataLayerAns.StageProcessAnalysisModel!=null && dataContext.DataLayerAns.StageProcessAnalysisDataModel!=null)
            {
                //传入阶段实体ID为255即采用分析结果阶段或优选结果阶段中最大的。
                #region 传入阶段为A255处理
                if (dataContext.DataLayerAns.StageProcessAnalysisModel.id == 0)
                {
                    if (dataContext.DataLayerOpt.StageProcessResultModel == null && dataContext.DataLayerAns.StageProcessAnalysisDataModel.id>0)
                    {
                        fage = true;
                        dataContext.DataLayerAns.StageProcessAnalysisModel = dataContext.DataLayerAns.StageProcessAnalysisDataModel;
                    }
                    else
                    {
                        if (dataContext.DataLayerAns.StageProcessAnalysisDataModel.id > dataContext.DataLayerOpt.StageProcessResultModel.id)
                        {
                           
                            dataContext.DataLayerAns.StageProcessAnalysisModel = dataContext.DataLayerAns.StageProcessAnalysisDataModel;
                        }
                        else
                        {
                            fage = true;
                            dataContext.DataLayerAns.StageProcessAnalysisModel = dataContext.DataLayerOpt.StageProcessResultModel;
                        }
                    }
                }
                else
                {
                    if (dataContext.DataLayerAns.StageProcessAnalysisDataModel!=null && dataContext.DataLayerOpt.StageProcessResultModel!=null)
                    {
                        if (dataContext.DataLayerAns.StageProcessAnalysisDataModel.id < dataContext.DataLayerOpt.StageProcessResultModel.id)
                        {
                            fage = true;
                        }
                    }
                    
                }
                //添加的数据为255
                if (dataContext.DataLayerAns.StageProcessAnalysisDataModel.id==0)
                {
                    fage = true;
                }
                #endregion
                //优选结果数据-为最新阶段
                StageProcessModel stageProcessModelOne = new StageProcessModel();
                //参与优选数据-为前一阶段数据
                StageProcessModel stageProcessModelTow = new StageProcessModel();

                stageProcessModelOne.id = dataContext.DataLayerAns.StageProcessAnalysisModel.id;
                stageProcessModelOne.path = dataContext.DataLayerAns.StageProcessAnalysisModel.path;
                stageProcessModelOne.Analysisresults = false;
                stageProcessModelOne.dataModel = XmlUtility.ConditionFirstOrDefaultDataModel(dataContext.DataLayerOpt.SourdatModleList, "", stageProcessModelOne.path);

                dataContext.InteractiveShow.LogShow("阶段信息传入阶段" + JsonConvert.SerializeObject(dataContext.DataLayerAns.StageProcessAnalysisModel));
                dataContext.InteractiveShow.LogShow("阶段信息分析数据阶段信息" + JsonConvert.SerializeObject(dataContext.DataLayerAns.StageProcessAnalysisDataModel));
                if (dataContext.DataLayerAns.StageProcessAnalysisModel.id>dataContext.DataLayerAns.StageProcessAnalysisDataModel.id)
                {
                    stageProcessModelTow.id = dataContext.DataLayerAns.StageProcessAnalysisDataModel.id;
                    stageProcessModelTow.path = dataContext.DataLayerAns.StageProcessAnalysisDataModel.path;
                    stageProcessModelTow.Analysisresults = true;
                    stageProcessModelTow.dataModel = XmlUtility.ConditionFirstOrDefaultDataModel(dataContext.DataLayerAns.AnalysisResultsDataModel.dataModelList, "", stageProcessModelTow.path);
                }
                else
                {
                    StageModel stageModel = ObtainStage(stageModelConfig, stageProcessModelOne.id);
                    if (stageModel!=null)
                    {
                        stageProcessModelTow.id =Convert.ToInt32(stageModel.id);
                        stageProcessModelTow.path = stageModel.path;
                        stageProcessModelTow.Analysisresults = true;
                        stageProcessModelTow.dataModel = XmlUtility.ConditionFirstOrDefaultDataModel(dataContext.DataLayerOpt.SourdatModleList, "", stageProcessModelTow.path);
                    }
                }
                if (stageProcessModelOne.path!=null && stageProcessModelTow.path!=null)
                {
                    Optimization(stageProcessModelOne, stageProcessModelTow, stageopConfig,fage,sameNodeConfig);
                }

            }
        }

        /// <summary>
        /// 跨阶段优选开始
        /// </summary>
        /// <param name="stageProcessModelOne"></param>
        /// <param name="stageProcessModelTow"></param>
        public void Optimization(StageProcessModel stageProcessModelOne, StageProcessModel stageProcessModelTow,string stageOpConifg, bool fage,SameNodeConfig sameNodeConfig) 
        {
            //本次数据根节点
            DataModel towDataModel = stageProcessModelTow.dataModel;
         
            //最新阶段数据
            DataModel oneDataModel = stageProcessModelOne.dataModel;
          
            List<DataModel> oneDataModelList = new List<DataModel>();
            //上次阶段数据
            List<DataModel> towDataModelList = new List<DataModel>();
            XmlUtilCommon xmlUtilCommon = new XmlUtilCommon() { dataContext = dataContext };
            //本次数据根节点
            //上次数据根节点
            string replacexml = stageProcessModelTow.path.Replace("详情", "");
            Regex r = new Regex(@"\[[^,，。;；/]*?\]");
            MatchCollection mc = r.Matches(replacexml);
            for (int i = 0; i < mc.Count; i++)
            {
                replacexml = replacexml.Replace(mc[i].Value, "");
            }
            oneDataModelList = SubordinateDataModelList(dataContext.DataLayerOpt.SourdatModleList, oneDataModel);
            if (fage)
            {
                towDataModelList = SubordinateDataModelList(dataContext.DataLayerAns.AnalysisResultsDataModel.dataModelList, towDataModel);
            }
            else
            {
                towDataModelList = SubordinateDataModelList(dataContext.DataLayerOpt.SourdatModleList, towDataModel);
            }
            
            //地址变量处理当前数据源
            List<DataModel> onedataModelList = JsonConvert.DeserializeObject<List<DataModel>>(JsonConvert.SerializeObject(oneDataModelList));
            List<DataModel> twodataModelList = JsonConvert.DeserializeObject<List<DataModel>>(JsonConvert.SerializeObject(towDataModelList));

            //当前阶段转换通用模板结果
            List<DataModel> oneResultList = new List<DataModel>();
            //上次阶段结果通用模板结果
            List<DataModel> towResultList = new List<DataModel>();
            //转换结构为通用模板
            DataModel dataModelroot = new DataModel();
            dataModelroot.ID = "0";
            dataModelroot.ParentId = "";
            dataModelroot.sourceData = new SourceData();
            dataModelroot.sourceData.sourceList = new List<Source>();
            Source source = new Source();
            source.IsCheck = "1";
            source.SourceCode = dataContext.DataLayerOpt.SourceCode;
            source.SourceID = dataContext.DataLayerOpt.SourceCode;
            dataModelroot.sourceData.sourceList.Add(source);
            dataModelroot.XmlPath = "通用模板";
            onedataModelList.FirstOrDefault(a => a.ID == oneDataModel.ID).ParentId = ""; 
            twodataModelList.FirstOrDefault(a => a.ID == towDataModel.ID).ParentId = "";

            oneResultList = onedataModelList;
            towResultList = twodataModelList;
            //DataModel dataCauseOneModel = oneResultList.FirstOrDefault(a => a.XmlPath.EndsWith("案由要素"));
            //if (dataCauseOneModel!=null)
            //{
            //    List<DataModel> dataCauseOneModelList = SubordinateDataModelList(oneResultList, dataCauseOneModel);
            //    oneResultList = oneResultList.Except(dataCauseOneModelList).ToList();
            //}
           
            //DataModel dataCauseTowModel = towResultList.FirstOrDefault(a => a.XmlPath.EndsWith("案由要素"));
            //if (dataCauseTowModel!=null)
            //{
            //    List<DataModel> dataCauseTowModelList = SubordinateDataModelList(towResultList, dataCauseTowModel);
            //    towResultList = towResultList.Except(dataCauseTowModelList).ToList();
            //}
            
            RestructureElment(towResultList, "", "");
            foreach (var oneModel in oneResultList)
            {
                oneModel.XmlPath = oneModel.XmlPath.Replace(replacexml, "");
            }
            foreach (var towModel in towResultList)
            {
                towModel.XmlPath = towModel.XmlPath.Replace(replacexml, "");
            }

            dataContext.InteractiveShow.LogShow("-------------------通用模板转换-----------------------");
            XmlDocument xmlDocumenttow = xmlUtilCommon.DataModelByXml(towResultList, "");
            XmlDocument xmlDocumentone = xmlUtilCommon.DataModelByXml(oneResultList, "");
            dataContext.InteractiveShow.LogShow("第一个数据源通用模板转换：" + xmlDocumentone.OuterXml);
            dataContext.InteractiveShow.LogShow("第二个数据源通用模板转换：" + xmlDocumenttow.OuterXml);
            foreach (var mode in oneResultList)
            {
                mode.State = "1";
            }
            StageOptimization(stageOpConifg, oneResultList, towResultList,sameNodeConfig);
            XmlDocument xmlDocumenttowccf = xmlUtilCommon.DataModelByXml(oneResultList, "");
            foreach (DataModel moderomve in oneResultList.Where(a => a.State == "2").ToList())
            {
                DataModel model = dataContext.DataLayerOpt.SourdatModleList.FirstOrDefault(a => a.ID == moderomve.ID);
                if (model!=null)
                {
                    dataContext.DataLayerOpt.SourdatModleList.Remove(model);
                }
            }
            oneResultList = oneResultList.Where(a => a.State != "2").ToList();
            XmlDocument xmlDocumenttowcc = xmlUtilCommon.DataModelByXml(oneResultList.Where(a => a.State != "2").ToList(), "");
            dataContext.InteractiveShow.LogShow("跨阶段优选结果@@：" + xmlDocumenttowcc.OuterXml);
            AssignmentStageResult(oneResultList, towDataModel.XmlPath);
        }

        public StageModel ObtainStage(StageConfig stageModelConfig,int id) 
        {
            id = id - 1;
            if (id>=0)
            {
                StageModel stageModel = stageModelConfig.stageModelList.FirstOrDefault(a => a.id == id.ToString());
                if (stageModel!=null)
                {
                    DataModel dataModel = XmlUtility.ConditionFirstOrDefaultDataModel(dataContext.DataLayerOpt.SourdatModleList, "", stageModel.path);
                    if (dataModel!=null)
                    {
                        return stageModel;
                    }
                    else
                    {
                        return ObtainStage(stageModelConfig, id);
                    }
                }
                else
                {
                    return ObtainStage(stageModelConfig, id);
                }
            }
            return null;
        }
        /// <summary>
        /// 将阶段优选结果赋值于优选结果中
        /// </summary>
        /// <param name="oneResultList">阶段优选结果</param>
        /// 
        public void AssignmentStageResult(List<DataModel> oneResultList,string xml)
        {
            foreach (DataModel dataModelStage in oneResultList)
            {
                DataModel resultModel = dataContext.DataLayerOpt.SourdatModleList.FirstOrDefault(a => a.ID == dataModelStage.ID);
                if (resultModel != null)
                {
                    resultModel.AttributesList = dataModelStage.AttributesList;
                    //结果为本次优选结果
                    resultModel.sourceData = dataModelStage.sourceData;
                    resultModel.State = dataModelStage.State;
                }
                else
                {//案件信息要素中心/案件审理阶段/详情
                    if (!string.IsNullOrEmpty(dataModelStage.ParentId))
                    {
                        if (dataModelStage.XmlPath.IndexOf("案件要素中心")==-1)
                        {
                            string xmlpath = xml.Replace(@"/详情", "")+"/";
                            dataModelStage.XmlPath = xmlpath + dataModelStage.XmlPath;
                        }

                        dataContext.DataLayerOpt.SourdatModleList.Add(dataModelStage);
                    }
                }
            }

        }

        /// <summary>
        /// 通用模板优选功能
        /// </summary>
        /// <param name="stageOpConfig">配置文件</param>
        /// <param name="onedataModelList">本阶段通用模板</param>
        /// <param name="twodataModelList">上阶段通用模板</param>
        /// <param name="twodataModelList">上阶段通用模板</param>
        public void StageOptimization(string stageOpConfig, List<DataModel> onedataModelList, List<DataModel> twodataModelList,SameNodeConfig sameNodeConfig)
        {
            //获取优选配置数据
            OptimizeConfig stageoptimizeConfig = XmlUtility.DeserializeToObject<OptimizeConfig>(stageOpConfig);
            OptimizConfig = stageoptimizeConfig;

            StageOptimizationClass stageOptimizationClass = new StageOptimizationClass() { dataContext = dataContext };
            stageOptimizationClass.CaseElmentOptimization(twodataModelList, "", onedataModelList, stageoptimizeConfig,sameNodeConfig);
        }

        /// <summary>
        /// 获取同节点判定
        /// </summary>
        /// <returns></returns>
        private SameNodeConfig GetSameNodeConfig()
        {
            var configModel = base.dataContext.DataLayerSys.GetConfigModel(this.ModuleName);
            
            if (base.dataContext.DataLayerAns.CaseCausesList.Count > 0)
            {
                if (!string.IsNullOrWhiteSpace(configModel.ConfigContent))
                {
                    XmlDocument xmlDocument = new XmlDocument();
                    xmlDocument.LoadXml(configModel.ConfigContent);
                    XmlNode xmlNode = xmlDocument.SelectSingleNode("/root/step[@code='samenodejudge']");
                    if (xmlNode != null)
                    {
                        Dictionary<string, string> dicElement = new Dictionary<string, string>();
                        string url = xmlNode.Attributes["executefile"].Value;
                        url = url.Replace("{casetype}", base.dataContext.DataLayerAns.CaseType).Replace("{causecode}", base.dataContext.DataLayerAns.CaseCausesList[0].CC_ID);
                        dicElement.Add("fileFullName", url);
                        string elementMessage = WebUtil.DoGet(ConfigRetrieval.GetConfigRetrieval.GetAppSettingString("systemapi") + "/api/WordParse/GetConfigFileContent", dicElement, "utf-8");
                        dynamic elementcofig = JsonConvert.DeserializeObject<dynamic>(elementMessage);
                        if (elementcofig.result.code.ToString() == "1")
                        {
                            string elementcofigstr = elementcofig.body;
                            sameNodeConfig = XmlUtility.DeserializeToObject<SameNodeConfig>(elementcofigstr);
                        }
                    }
                }
                else
                {
                    var config = configModel.ConfigDetail.FirstOrDefault(a => a.Code.ToLower() == "samenodejudge");
                    Dictionary<string, string> dicElement = new Dictionary<string, string>();
                    string url = config.FilePath;
                    url = url.Replace("{casetype}", base.dataContext.DataLayerAns.CaseType).Replace("{causecode}", base.dataContext.DataLayerAns.CaseCausesList[0].CC_ID);
                    dicElement.Add("fileFullName", url);
                    string elementMessage = WebUtil.DoGet(ConfigRetrieval.GetConfigRetrieval.GetAppSettingString("systemapi") + "/api/WordParse/GetConfigFileContent", dicElement, "utf-8");
                    dynamic elementcofig = JsonConvert.DeserializeObject<dynamic>(elementMessage);
                    if (elementcofig.result.code.ToString() == "1")
                    {
                        string elementcofigstr = elementcofig.body;
                        sameNodeConfig = XmlUtility.DeserializeToObject<SameNodeConfig>(elementcofigstr);
                    }
                }
            }
            return sameNodeConfig;
        }



    }
   
}
